package com.zsj.juc.lock;

import java.util.concurrent.TimeUnit;

/**
 * @author zsj
 * @version 1.0
 * @date 2024/4/19 18:52
 * @description 8锁案例说明
 */
public class Lock8Demo {
    //1、标准访问有ab两个线程  请问先打印邮件还是短信 (邮件 短信)
    //2.sendemail方法中加入暂停3秒钟 请问先打印邮件还是短信 (邮件 短信)
    //3.添加一个普通的hello方法 请问先打印邮件还是hello  (hello 邮件)?
    //4.两部手机,请问先打印邮件还是短信 (短信 邮件)
    //5.两个静态同步方法,1部手机 请问先打印邮件还是短信 (邮件 短信)
    //6.两个静态同步方法,2部手机 请问先打印邮件还是短信 (邮件 短信)
    //7.1个静态同步方法,1个普通同步方法,1部手机 请问先打印邮件还是短信 (短信 邮件)?
    //8.1个静态同步方法,1个普通同步方法,2部手机 请问先打印邮件还是短信 (短信 邮件)?

    /*
    总结
    1.2两个案例 锁的是当前对象this 同步代码块中锁的也是实列对象
    说明某一个时刻内 只能有一个线程去调用资源类中的一个同步方法 其它线程都必须等待
    3这个案例说明  没有被synchronized修饰的方法 并不会被锁 没有竞争
    4.因为是两个不同的对象 所以不会产生竞争 所以肯定是短信先打印 然后才是邮件
    5.6两个案例 static synchronized 和 synchronized 锁的不是一个东西
        static synchronized会让线程进入后其它的static synchronized方法出现竞争状态
        static synchronized 是一个类锁 而不是对象锁 这种锁法就是说不管你有几个这种类 都会将你这个类给锁住
    7.8是因为两个加锁的对象不同 所以不产生竞争

    */
    public static void main(String[] args) {
        Phone phone = new Phone();
        Phone phone2 = new Phone();
        new Thread(() -> {
//            phone.sendEmail();
            phone.sendEmail();
        }, "a").start();

        //这个sleep是保证a先执行
        try {
            TimeUnit.MILLISECONDS.sleep(200);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        new Thread(() -> {
//            phone.sendSms();
            phone.sendSms();

        }, "b").start();
    }
}

class Phone {

    //static synchronized 是类锁
    //synchronized 是对象锁

    public static synchronized void sendEmail() {
        try {
            TimeUnit.MILLISECONDS.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("----------send Email");
    }

    public synchronized void sendSms() {
        System.out.println("----------send sms");
    }

    public void hello() {
        System.out.println("hello");
    }
}
